﻿package com.google.ads.studio.creative.swipe {
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	
	import com.greensock.TweenLite;
	import com.greensock.easing.*;
	
	import com.google.ads.studio.creative.swipe.SwipeThumbnail;
	import com.google.ads.studio.creative.swipe.MediaWindow;
	
	/**
	* SwipeBar Class
	* 
	* @autor: Emilio Mora (emiliom@google.com)
	* @version: 0.2
	* @langversion AS3
	*
	*/	
	public class SwipeBar extends MovieClip {
		
		public const ON_OPEN_START:String = "onOpenStart";
		public const ON_OPEN_FINISH:String = "onOpenFinish";
		public const ON_CLOSE_START:String = "onCloseStart";
		public const ON_CLOSE_FINISH:String = "onCloseFinish";
		
		private const MAX_VEL:Number = 0;
		private const BAR_BOTTOM:Number = 21;
		private const BUTTON_TOP_MARGIN:Number = 5;
		
		private var _animatedShow:Boolean = true;
		private var _animatedShowTime:Number = 0.5;
		private var unitHeight:Number;
		private var barHeight:Number;
		private var dragRect:Rectangle;
		private var velocityTimer:Timer;
		private var velocity:Number = 0;
		private var initY:Number;
		private var pastY:Number;
		private var initMouseY:Number;
		private var isOpen:Boolean = false;
		private var thumbsList:Array;
		private var windowsArray:Array;
		
		/**
		* Constructor.
		*
		*/
		public function SwipeBar() {
			
			thumbsList = new Array();
			windowsArray = new Array();
			
			dragArea_btn.alpha = 0;		
			
			init();
		}
		
		/**
		* Initial properties, variables and listeners.
		*
		*/
		private function init() {
			initY = this.y;
			pastY = this.y;
			
			dragRect = new Rectangle(0, initY, 0, Math.abs(initY));
			velocityTimer = new Timer(100);
			
			dragArea_btn.addEventListener(MouseEvent.MOUSE_DOWN, startDragBar);
			dragArea_btn.addEventListener(MouseEvent.CLICK, onBarClick);
			dragButton_btn.addEventListener(MouseEvent.MOUSE_DOWN, startDragBar);
			dragButton_btn.addEventListener(MouseEvent.CLICK, onBarClick);
			velocityTimer.addEventListener(TimerEvent.TIMER, updateVelocity);
		}
		
		/**
		* Update the value of the velocity and the pastY with a timer when the bar is in drag.
		* 
		* @param event TimerEvent.
		*/
		private function updateVelocity(event:TimerEvent) {
			velocity = this.y - pastY;
			pastY = this.y;
		}
		
		/**
		* Check if the velocity of the drag is positive or negative to open or close the bar when the user release the drag.
		* 
		*/
		private function checkVelocity() {
			
			if (initMouseY != parent.mouseY) {
				if ( Math.abs(velocity) > 0 ) {
					if (velocity > 0) {
						open();
					} else {
						close();
					}
				}else{
					if (isOpen) {
						close();
					} else {
						open();
					}
				}
			}			
		}
		
		/**
		* Start the drag and the timer to update the value of the velocity when the user click to drag.
		* 
		* @param event MouseEvent.
		*/
		private function startDragBar(event:MouseEvent) {
			this.startDrag(false, dragRect); 
			stage.addEventListener(MouseEvent.MOUSE_UP, stopDragBar);
			pastY = this.y;
			initMouseY = parent.mouseY;
			velocityTimer.start();
			TweenLite.to(swipeText_mc, 0.5, {alpha:0});
		}
		
		/**
		* Stop the drag, the timer and check the velocity to open or close the bar.
		* 
		* @param event MouseEvent.
		*/
		private function stopDragBar(event:MouseEvent) {
			stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragBar);
			this.stopDrag();
			velocityTimer.stop();
			checkVelocity();
		}
		
		/**
		* Check if the user click on the bar to open/close automatically.
		* 
		* @param event MouseEvent.
		*/
		private function onBarClick(event:MouseEvent) {
			if (initMouseY == parent.mouseY) {
				if (isOpen) {
					close(1);
				} else {
					open(1);
					TweenLite.to(swipeText_mc, 0.5, {alpha:0});
				}
				
			}
		}
		
		/**
		* Show the panel when the user click in a thumbnail.
		* 
		* @param event MouseEvent.
		*/
		private function onThumbClick(event:MouseEvent) {
			for (var i:int = 0; i < windowsArray.length; i++) {
				if (i == event.currentTarget.id) {
					windowsArray[i].show();
				} else {
					windowsArray[i].hide();
				}
			}
		}
				
		/**
		* Initial animation that close the panel with a Bounce effect.
		* 
		* @param time Time of the animation in seconds (default: 2).
		*/
		public function introAnim(time:Number = 2) {
			this.y = 0;
			isOpen = false;
			TweenLite.to(this, time, {y:initY, ease:Bounce.easeOut, delay:0.5, onComplete:function (path) {
				TweenLite.to(swipeText_mc, 0.5, {alpha:1});
			}, onCompleteParams:[this]});
		}
		
		/**
		* Add a thumbnail to the swipe bar with an image and/or youtube video.
		* 
		* @param thumbnail Image of the thumbnail, can be a MovieClip, a BitmapData or a URL path to an image.
		* @param thumbX X position of the thumbnail.
		* @param thumbY Y position of the thumbnail.
		* @param image Background image of the panel that opens when the user click in the thumbnail.
		* @param videoID ID of the video hosted in youtube (optional).
		* @param videoX X position of the video.
		* @param videoY Y position of the video.
		* @param videoWidth Width of the video.
		* @param videoHeight Height of the video.
		*/
		public function addImage(thumbnail:Object, thumbX:Number = 0, thumbY:Number = 0, image:Object = null, videoID:String = null, videoX:Number = 0, videoY:Number = 0, videoWidth:Number = 0, videoHeight:Number = 0) {
			var thumb:SwipeThumbnail = new SwipeThumbnail(thumbsList.length, thumbnail);
			thumb.x = thumbX;
			thumb.y = thumbY;
			thumbsList.push(thumb);				
			content_mc.addChild(thumb);
			
			thumb.addEventListener(MouseEvent.CLICK, onThumbClick);
			
			var swipeImage:MediaWindow = new MediaWindow(image, videoID, videoX, videoY, videoWidth, videoHeight);
			swipeImage.animatedShow = _animatedShow;
			swipeImage.animatedShowTime = _animatedShowTime;
			windowsArray.push(swipeImage);
			this.addChild(swipeImage);
		}

		/**
		* Open the Swipe Bar.
		* 
		* @param time Time of the animation in seconds (default: 0.3).
		*/
		public function open(time:Number = 0.3) {
			isOpen = true;
			dispatchEvent( new Event(ON_OPEN_START) );
			TweenLite.to(this, time, {y:0, ease:Quad.easeOut, onComplete:function (path) {
				path.dispatchEvent( new Event(ON_OPEN_FINISH) );
			}, onCompleteParams:[this]});
			
		}
		
		/**
		* Close the Swipe Bar.
		* 
		* @param time Time of the animation in seconds (default: 0.3).
		*/
		public function close(time:Number = 0.3) {
			isOpen = false;
			dispatchEvent( new Event(ON_CLOSE_START) );
			TweenLite.to(this, time, {y:initY, ease:Quad.easeOut, onComplete:function (path) {
				path.dispatchEvent( new Event(ON_CLOSE_FINISH) );
				TweenLite.to(swipeText_mc, 0.5, {alpha:1});
			}, onCompleteParams:[this]});
		}
		
		//*****GETTERS*****
		
		/**
		* Get an array with the panels added to the Swipe Bar.
		* 
		* @return Array with the panels.
		*/
		public function get panels():Array {
			return windowsArray;
		}
		
		/**
		* animatedShow property, if is true the open/close is animated.
		* 
		* @return value of the property.
		*/
		public function get animatedShow():Boolean {
			return _animatedShow;
		}
		
		/**
		* animatedShowTime property, time of the animation of the open/close if is animated.
		* 
		* @return value of the property.
		*/
		public function get animatedShowTime():Number {
			return _animatedShowTime;
		}
		
		//*****SETTERS*****

		/**
		* animatedShow property, if is true the open/close is animated.
		* 
		* @param value value of the property.
		*/
		public function set animatedShow(value:Boolean) {
			_animatedShow = value;
			for (var i:int = 0; i < windowsArray.length; i++) {
				windowsArray[i].animatedShow = _animatedShow;
			}
		}
		
		/**
		* animatedShowTime property, time of the animation of the open/close if is animated.
		* 
		* @param value value of the property.
		*/
		public function set animatedShowTime(value:Number) {
			_animatedShowTime = value;
			for (var i:int = 0; i < windowsArray.length; i++) {
				windowsArray[i].animatedShowTime = _animatedShowTime;
			}
		}		
		
	}
	
}
